#pragma once

#include <sstream>

#include <string>
#include <iostream>
#include <vector>
#include <unordered_map>

#include "uncopyable.hpp"

const static std::string com_sep = "\r\n";
const static std::string req_sep = ": ";

class HttpRequest // 根据Http请求的结构确定
{
private:
    /// @brief 获得正文内容之前的信息
    /// @param reqstr
    /// @return 当前调用获取的一行字符串
    std::string Getline(std::string &reqstr)
    {
        auto pos = reqstr.find(com_sep);
        if (pos == std::string::npos)
            return std::string();

        std::string line = reqstr.substr(0, pos);      // 如果找到空行，则pos==0，截取出来的line是一个空串
        reqstr.erase(0, line.size() + com_sep.size()); // 若是，同样删掉空串
        if (line.empty())
            return com_sep; // 以这种方式返回，表示已经读取到空行

        return line;
    }
    void PraseReqLine()
    {
        // 创建一个字符串流，类似于cin，可以以空格为分隔符分别输入给多个变量
        std::stringstream ss(_req_line);
        ss >> _method >> _url >> _verson;
    }
    void PraseReqHeader()
    {
        for (auto &header : _req_headers)
        {
            auto pos = header.find(req_sep);
            if(pos == std::string::npos)
                continue;
            std::string k = header.substr(0,pos);
            std::string v = header.substr(pos + req_sep.size());
            if(k.empty() || v.empty())
                continue;
            _headers_kv.insert(std::make_pair(k,v));
        }
    }

public:
    HttpRequest()
        : _blank_line(com_sep)
    {
    }
    /// @brief 序列化，解析http的请求内容
    /// @param reqstr 请求以字符串形式发送
    void Deserialize(std::string &reqstr)
    {
        // 基础反序列化
        _req_line = Getline(reqstr); // 获取请求行
        std::string header;
        while (true)
        {
            header = Getline(reqstr);
            if (header.empty())
                break;
            if (header == com_sep)
                break;

            _req_headers.push_back(header);
        }
        // 到这里，请求行和报头，空行被获取完
        if (!reqstr.empty())
            _body_text = reqstr;

        // 进一步反序列化(填写属性字段)

        PraseReqLine();
        PraseReqHeader();
    }

    void Print()
    {
        std::cout << "请求行:" << _req_line << std::endl;

        for (auto &header : _req_headers)
        {
            std::cout << "报头:" << header << std::endl;
        }
        std::cout << "空行:" << _blank_line;
        std::cout << "正文:" << _body_text << std::endl;
        std::cout<< "method:"<<_method<<std::endl;
        std::cout<< "url:"<<_url<<std::endl;
        std::cout<< "verson:"<<_verson<<std::endl;
        
        for(auto header:_headers_kv)
        {
            std::cout<<header.first <<" "<<header.second<<std::endl;
        }
    }

private:
    // 基本的httprequest的格式
    std::string _req_line; // 请求行
    std::vector<std::string> _req_headers;
    std::string _blank_line;
    std::string _body_text;

    // 更具体的属性字段，需要进一步反序列化
    std::string _method;
    std::string _url;
    std::string _verson;
    std::unordered_map<std::string, std::string> _headers_kv; // 存储属性字段KV结构
};

class HttpReponse // 根据Http的响应的结构确定
{

private:
    std::string _status;
    std::vector<std::string> _resp_headers;
    std::string _blank_line;
    std::string _resp_body_text;
};

class HttpServer : public uncopyable
{
public:
    HttpServer() {}
    std::string HanderHttpRequest(std::string &reqstr)
    {
#ifdef DEBUG
        std::cout << "---------------------------------------------" << std::endl;
        std::cout << reqstr;
        std::string responsestr = "HTTP/1.1 200 OK\r\n";
        responsestr += "Content-Type: text/html\r\n";
        responsestr += "\r\n";
        responsestr += "<html><h1>hello linux!</h1></html>";

        return responsestr;
#else
        HttpRequest req;
        req.Deserialize(reqstr);
        req.Print();

        return std::string();
#endif
    }
    ~HttpServer() {}

private:
};